<?php

namespace app\admin\listener;

use app\admin\listener\log\KeywordFilter;
use app\admin\listener\log\LengthFilter;
use app\common\Constants;
use app\common\facade\HttpHelper;
use app\common\facade\Principal;
use app\admin\model\admin\Log as LogModel;
use think\facade\Log;

class AdminLog
{
    /**
     * 定义过滤器链条
     * @var array
     */
    protected array $filters = [
        KeywordFilter::class,
        LengthFilter::class,
    ];

    public function handle($event): void
    {
        try {
            $content = request()->except(config('filter.excluded_fields', []));

            if (!$content) {
                return;
            }

            foreach ($this->filters as $filterClass) {
                $filterInstance = app($filterClass);
                $filterInstance->apply($content);
            }

            $log_content = '';
            switch ($event['type']) {
                case Constants::LOG_TYPE_LOGIN:
                case Constants::LOG_TYPE_OPERATE:
                    // 操作参数
                    $log_content = json_encode($content, JSON_UNESCAPED_UNICODE);
                    break;
                case Constants::LOG_TYPE_EXCEPTION:
                    // 异常信息
                    $log_content = $event['content'];
                    break;
            }

            $data['app'] = app('http')->getName();
            $data['username'] = Principal::hasLogin() ? Principal::getUserName() : '--';
            $data['url'] = str_replace('.', '/', strtolower(parse_url(request()->url())['path']));
            $data['agent'] = HttpHelper::getBrowser();
            $data['os'] = HttpHelper::getOs();
            $data['content'] = $log_content;
            $data['ip'] = request()->ip();
            $data['type'] = $event['type'];
            $data['status'] = 1;

            LogModel::create($data);

        } catch (\Exception $e) {
            trace([
                'file' => $e->getFile(),
                'line' => $e->getLine(),
                'error_message' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ], 'debug');
            throw $e;
        }

    }
}